/*
    兼容ie版本
    完全跨域解决方案
    目标：构建规则化页面不同域名的iframe页面信息交互
*/
function Dubbo(isInt, sign) {
    //本地目录列表 key:func 只用于本地注册函数到远程，同时记录在本地
    this.localFuncMap = {};
    //远程目录列表 相当于注册方法列表 key:window
    this.remoteFuncMap = {};
    //自身窗口
    this.window = window;
    //顶级窗口
    this.top = window.top;
    //是否为注册中心
    this.isRegistry = (this.window == this.top);
    //消息头key
    this.HEADER_KEY = "message_header_key";
    //消息头内容
    this.HEADER_INFO = sign || "tuanche";
    //初始化
    if (isInt) {
        this.init();
    }
}


//初始化
Dubbo.prototype.init = function () {
    let thiz = this;
    let backFunc = function (e) {
        //console.log(e);
        let data = e.data;
        //进行信息验证
        if (typeof data == "object"
            && thiz.HEADER_KEY in data
            && data[thiz.HEADER_KEY] == thiz.HEADER_INFO) {
            //判断是不是注册中心
            if (thiz.isRegistry) {
                if (data["type"] == "run" && data["meg"]["funcKey"] in thiz.remoteFuncMap) {
                    let meg = data["meg"];
                    let targetWin = thiz.remoteFuncMap[meg["funcKey"]];
                    //目标window为顶级window则直接执行
                    if (targetWin == thiz.window) {
                        thiz.localFuncMap[meg["funcKey"]](meg["agrs"]);
                    } else {
                        thiz.sendMeg("run", meg, targetWin);
                    }
                }
                if (data["type"] == "reg") {
                    let funcKey = data["meg"];
                    console.log("收到函数注册key:" + funcKey + "|窗口:" + e.source);
                    thiz.remoteFuncMap[funcKey] = e.source;
                }
            } else {
                //非注册中心 就执行目标函数
                if (data["type"] == "run" && data["meg"]["funcKey"] in thiz.localFuncMap) {
                    let meg = data["meg"];
                    thiz.localFuncMap[meg["funcKey"]](meg["agrs"]);
                }
            }
        }
    }

    if (this.window.addEventListener) {
        this.window.addEventListener('message', backFunc, false);
    } else if (window.attachEvent) {
        window.attachEvent("onmessage", backFunc);
    }
}

/**
     * 发送消息到指定窗口
     * @param type "reg|run"
     * @param meg
     * @param targetWindow
     */
Dubbo.prototype.sendMeg = function (type, meg, targetWindow) {
    //消息加签
    let info = {};
    info[this.HEADER_KEY] = this.HEADER_INFO;
    info["meg"] = meg;
    info["type"] = type;
    targetWindow.postMessage(info, "*");
}

/**
 * 向顶级注册函数
 * @param funcKey 函数key
 * @param origin 选填
 */
Dubbo.prototype.regRemoteFunc = function (funcKey, func) {
    this.localFuncMap[funcKey] = func;
    //如果是注册中心注册函数 那么不再发送远程注册。
    if (this.isRegistry) {
        this.remoteFuncMap[funcKey] = this.window;
    } else {
        this.sendMeg("reg", funcKey, this.top);
    }
}

/**
 * 执行注册函数
 * @param funcKey 函数key
 * @param origin 选填
 */
Dubbo.prototype.runRemoteFunc = function (funcKey, agrs, origin) {
    this.sendMeg("run", { "funcKey": funcKey, "agrs": agrs }, this.top);
}